package io.shallwe._admin.line;

import java.util.Date;
import java.util.List;

import com.jfinal.aop.Aop;
import io.shallwe._admin.basedata.hangerframe.HangerFrameService;
import io.shallwe.common.model.*;
import io.shallwe.stovingoven.StovingOvenTemperatureService;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;

import com.jfinal.kit.Ret;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.Record;

import io.shallwe._admin.basedata.scanner.ScannerService;

/**
   *  入口上线扫描服务
 * @author 王小伟
 * @date   2019-06-10 21:17:33 
 */
public class EnterScanService {
	ScannerService scannerService = Aop.get(ScannerService.class);
	StovingOvenTemperatureService stovingOvenTemperatureService = Aop.get(StovingOvenTemperatureService.class);
	HangerFrameService rackFrameService = Aop.get(HangerFrameService.class);

	private EnterBuffer dao= new EnterBuffer().dao();

	private EnterScan enterScanDao= new EnterScan().dao();

	public EnterBuffer findById(String id) {
		return dao.findById(id);
	}
	
	public Ret paginate() {
		Page<Record> paginate = Db.template("enterBuffer.paginate").paginate(1, 100);
		return Ret.ok("total", paginate.getTotalRow()).set("rows", paginate.getList());
	}
	
	public List<Record> enterBufferInfo() {
		Page<Record> paginate = Db.template("enterBuffer.paginate").paginate(1, 100);
		return paginate.getList();
	}

	/**
	 * 人工添加扫描记录
	 * @param enterBuffer
	 * @param accountId
	 * @return
	 */
	public Ret save(EnterBuffer enterBuffer,String accountId) {
		if(isHangerNoExists(enterBuffer.getHangerNo(),-1)) {
			return Ret.fail("msg","电泳框编号已经存在，请输入其他的电泳框编号");
		}
		
		if(isBarcodeExists(enterBuffer.getTraceNo(),-1)) {
			return Ret.fail("msg","追溯编号已经存在，请输入其他的追溯编号");
		}

		enterBuffer.setUpdateTime(new Date());
		enterBuffer.setAccountId(accountId);
		enterBuffer.save();
		return Ret.ok("msg","操作成功");
	}

	/**
	 * 手动更新上线缓冲区
	 * @param enterBuffer
	 * @param accountId
	 * @return
	 */
	public Ret update(EnterBuffer enterBuffer,String accountId) {
		
		if(isHangerNoExists(enterBuffer.getHangerNo(),enterBuffer.getId())) {
			return Ret.fail("msg","电泳框编号已经存在，请输入其他的电泳框编号");
		}
		
		if(isBarcodeExists(enterBuffer.getBarcode(),enterBuffer.getId())) {
			return Ret.fail("msg","追溯编号已经存在，请输入其他的追溯编号");
		}
		
		enterBuffer.setUpdateTime(new Date());
		enterBuffer.setAccountId(accountId);
		enterBuffer.update();
		return Ret.ok("msg","操作成功");
	}
	
	public Ret  delete(String id,int type) {
		if(type==1){
			enterScanDao.deleteById(id);
		}
		if(type==2) {
			dao.deleteById(id);
		}
		return Ret.ok("msg","操作成功");
	}
	
	public Ret scan(String code,String ip) {
		code=StringUtils.replace(code, "\r", "");
		code=StringUtils.replace(code, "\n", "");
		code=StringUtils.replace(code, "\r\n", "");
		code=StringUtils.replace(code, " ", "");
		Scanner scanner = scannerService.findByIp(ip);
		if(scanner!=null) {
			ScannerRecord scannerRecord = new ScannerRecord().setUpdateTime(new Date());
			scannerRecord.setScannerId(scanner.getId());
			scannerRecord.setScannerType(scanner.getScannerType());
			scannerRecord.setRawText(code).setHangerNo("");
			scannerRecord.setManualFlag(ScannerRecord.MANUAL_SCAN);
			scannerRecord.setStatusFlag(ScannerRecord.INIT);
			//用户登陆
			if (StringUtils.startsWith(code, "U#")) {
				String employeeNumber = StringUtils.substringAfter(code, "U#");
				scannerService.bindAccountByIp(ip, employeeNumber);
			}
			//挂具编号
			else if (StringUtils.startsWith(code, "R")) {
				scanHangerNo(code, ip);
				scannerRecord.setHangerNo(code);
			}
			//扫描追溯单
			else if (StringUtils.startsWith(code, "F")) {
				scanTraceCode(code, ip);
			}
			//扫描物料数量
			else if (StringUtils.startsWith(code, "Q")) {
				String materialCountStr = StringUtils.substringAfter(code, "Q");
				try {
					Integer materialCount = NumberUtils.toInt(materialCountStr);
					scanMaterialCount(materialCount, ip);
				} catch (Exception e) {
					//do nothing;
					e.printStackTrace();
				}
			} else {
				//do nothing;
			}
			scannerRecord.save();
		}


		return Ret.ok("msg","操作成功");
	}

	/**
	 * 扫描挂具
	 * @param hangerNo
	 * @param ip
	 */
	public void scanHangerNo(String hangerNo, String ip) {
		EnterScan enterScan = enterScanDao.template("enterBuffer.findScanTempInfo",ip).findFirst();
		Account account = scannerService.findAccountByIp(ip);
		String accuntId="";
		if(account!=null){
			accuntId=account.getId();
		}
		HangerFrameMiddle hangerFrameMiddle = rackFrameService.findByHangerNo(hangerNo);
		String frameNo = hangerFrameMiddle.getFrameNo();
		if(frameNo==null){
			frameNo="";
		}
		if(enterScan==null){
			enterScan = new EnterScan();
			enterScan.setFrameNo(frameNo).setMaterialCount(-1);
			enterScan.setAccountId(accuntId).setCreateTime(new Date()).setHangerNo(hangerNo).setIpAddress(ip).setStatusFlag(1);
			enterScan.save();
			return;
		}

		if(StrKit.isBlank(enterScan.getBarcode()) || enterScan.getMaterialCount()<0){
			enterScan.setAccountId(accuntId).setHangerNo(hangerNo).setUpdateTime(new Date());
			enterScan.setFrameNo(frameNo).update();
			return;
		}
		enterScan.setAccountId(accuntId).setFrameNo(frameNo);
		enterScan.setHangerNo(hangerNo);

		hangerMoveToBuffer(enterScan);
	}


	/**
	 * 扫描追溯编号
	 * @param code
	 * @param ip
	 */
	public void scanTraceCode(String code,String ip) {

		String[] codes=StringUtils.split(code,"#");
		if(codes.length!=3) {
			return;
		}
		//追溯编号
		String traceNo=codes[0];
		traceNo=StringUtils.substring(traceNo, 1);
		if(StringUtils.isBlank(traceNo)) {
			traceNo="";
		}
		//物料编号
		String materialNo=codes[1];
		if(materialNo==null){
			materialNo="";
		}
		//条码
		String barcode=codes[2];
		if(barcode==null){
			barcode="";
		}
		EnterScan enterScan = enterScanDao.template("enterBuffer.findScanTempInfo",ip).findFirst();
		if(enterScan==null){
			enterScan = new EnterScan();
			enterScan.setTraceNo(traceNo).setBarcode(barcode).setMaterialNo(materialNo).setMaterialCount(-1);
			enterScan.setAccountId("").setCreateTime(new Date()).setIpAddress(ip).setStatusFlag(1);
			enterScan.save();
			return;
		}
		if(StrKit.isBlank(enterScan.getHangerNo()) || enterScan.getMaterialCount()<0){
			enterScan.setTraceNo(traceNo).setBarcode(barcode).setMaterialNo(materialNo);
			enterScan.setAccountId("").setUpdateTime(new Date()).setIpAddress(ip).setStatusFlag(1);
			enterScan.update();
			return;
		}
		enterScan.setTraceNo(traceNo).setBarcode(barcode).setMaterialNo(materialNo);
		enterScan.setTraceNo(traceNo).setBarcode(barcode).setMaterialNo(materialNo);
		enterScan.setAccountId("").setUpdateTime(new Date()).setIpAddress(ip);
		hangerMoveToBuffer(enterScan);
	}

	/**
	 * 扫描物料数量
	 * @param materialCount
	 * @param ip
	 */
	public void scanMaterialCount(Integer materialCount,String ip) {
		EnterScan enterScan = enterScanDao.template("enterBuffer.findScanTempInfo",ip).findFirst();
		if(enterScan==null){
			enterScan = new EnterScan();
			enterScan.setMaterialCount(materialCount);
			enterScan.setAccountId("").setCreateTime(new Date()).setIpAddress(ip).setStatusFlag(1);
			enterScan.save();
			return;
		}
		if(StrKit.isBlank(enterScan.getBarcode()) || enterScan.getMaterialCount()<0){
			enterScan.setMaterialCount(materialCount).setUpdateTime(new Date());
			enterScan.update();
			return;
		}
		enterScan.setMaterialCount(materialCount);
		//更新状态并进入缓冲区
		hangerMoveToBuffer(enterScan);
	}


	/**
	 * 扫描记录进入上线缓冲区
	 * @param enterScan
	 */
	public void hangerMoveToBuffer(EnterScan enterScan){
		//过滤没有条码的扫描记录
		if(StrKit.isBlank(enterScan.getBarcode())) {
			enterScan.setHangerNo("")
					.setFrameNo("")
					.setMaterialCount(-1)
					.setMaterialNo("")
					.setTraceNo("")
					.setBarcode("")
					.setUpdateTime(new Date()).setStatusFlag(1)
					.update();
			return;
		}
		//过滤线上或者上线缓冲区已经存在情况
		if(StrKit.isBlank(enterScan.getBarcode())==false) {
			Integer id = Db.template("enterBuffer.isCodeRepeatInBufferOrLine", enterScan.getBarcode(),enterScan.getHangerNo()).queryInt();
			if (id != null) {
				enterScan.setHangerNo("")
						.setFrameNo("")
						.setMaterialCount(-1)
						.setMaterialNo("")
						.setTraceNo("")
						.setBarcode("")
						.setUpdateTime(new Date())
						.update();
				return;
			}
		}

		//避免重复扫描
		Integer id = Db.template("enterBuffer.isCodeRepeatInScanTempArea",
				enterScan.getBarcode(),
				enterScan.getHangerNo(),
				enterScan.getId()
		).queryInt();
		if (id != null) {
			Db.template("enterBuffer.clearRepeatData", enterScan.getHangerNo()).update();
		}


		enterScan.setUpdateTime(new Date()).setStatusFlag(2).update();

		EnterBuffer buffer = dao.template("enterBuffer.getByHangerNoFromBuffer",enterScan.getHangerNo()).findFirst();
		if(buffer!=null){
			buffer.setAccountId(enterScan.getAccountId())
					.setBarcode(enterScan.getBarcode())
					.setTraceNo(enterScan.getTraceNo())
					.setMaterialNo(enterScan.getMaterialNo())
					.setFrameNo(enterScan.getFrameNo())
					.setHangerNo(enterScan.getHangerNo())
					.setMaterialCount(enterScan.getMaterialCount())
					.setUpdateTime(new Date());
			buffer.update();
		}else{
			buffer = new EnterBuffer().setCreateTime(new Date()).setStatusFlag(1);
			buffer.setAccountId(enterScan.getAccountId())
					.setBarcode(enterScan.getBarcode())
					.setTraceNo(enterScan.getTraceNo())
					.setMaterialNo(enterScan.getMaterialNo())
					.setFrameNo(enterScan.getFrameNo())
					.setHangerNo(enterScan.getHangerNo())
					.setMaterialCount(enterScan.getMaterialCount())
					.setUpdateTime(new Date());
			buffer.save();
		}
	}

	/**
	 * 自动扫描
	 * @param hangerNo
	 * @return
	 */
	
	public Ret autoScan(String hangerNo) {
		//炉温检查
		stovingOvenTemperatureService.checkAndCalmDown();
		stovingOvenTemperatureService.checkAndRiseTemperature();

		Scanner autoOnlineScanner = scannerService.findAutoOnlineScanner();
		if(autoOnlineScanner!=null){
			ScannerRecord scannerRecord = new ScannerRecord();
			scannerRecord.setHangerNo(hangerNo)
					.setManualFlag(ScannerRecord.MANUAL_SCAN)
					.setStatusFlag(ScannerRecord.INIT)
					.setUpdateTime(new Date())
					.setScannerId(autoOnlineScanner.getId())
					.setScannerType(autoOnlineScanner.getScannerType())
					.setRawText(hangerNo).save();
		}
		return Ret.ok("msg","操作成功");
	}

	/**
	 * 判断缓冲区里是否有相同的挂具
	 * @param hangerNo
	 * @param id
	 * @return
	 */
	public boolean isHangerNoExists(String hangerNo, int id) {
		hangerNo=hangerNo.toLowerCase().trim();
		String sql="select top 1 id from t_enter_buffer where lower(hanger_no) = ? and id != ?";
		return Db.queryStr(sql,hangerNo,id)!=null;
	}

	/**
	 * 判断缓冲区里是否有相同的条码
	 * @param barcode
	 * @param id
	 * @return
	 */
	public boolean isBarcodeExists(String barcode, int id) {
		barcode=barcode.toLowerCase().trim();
		String sql="select top 1 id from t_enter_buffer where lower(barcode) = ? and id != ?";
		return Db.queryStr(sql,barcode,id)!=null;
	}

	public List<EnterBuffer> listAllValidBufferData(){
		return dao.template("enterBuffer.listAllValidBufferData").find();
	}

	public  List<EnterScan> listAllValidScanData(){
		return enterScanDao.template("enterBuffer.listAllValidScanData").find();
	}
}
